import java.util.*;

public class Homework {
    static public Scanner sc = new Scanner(System.in);

    static public void p(String format, Object ... obj) {
        System.out.printf(format, obj);
    }

// 交换两个变量的值(二种方法)
    static public void  swapVal() {
        int a = 5, b = 3;

        System.out.printf("原来的值: a = %d, b = %d\n", a, b);
        int c = a;
        a = b;
        b = c;
        System.out.printf("第一种交换的结果: a = %d, b = %d\n", a, b);

        a ^= b;
        b ^= a;
        a ^= b;
        /*
         * a += b;
         * b = a - b;
         * a -= b;
         */
        System.out.printf("第二种交换的结果: a = %d, b = %d\n", a, b);
    }

    // 封装获取整型数
    static public int getInt(String prompt, int ... range) {
        int num;
        int start = Integer.MIN_VALUE, end = Integer.MAX_VALUE;

        if (range.length == 1) {
            end = range[0];
        } else if (range.length > 1) {
            start = range[0];
            if (range[1] > start)
                end = range[1];
        }

        while (true) {
            System.out.printf(prompt);
            num = sc.nextInt();
            if (num >= start && num <= end)
                break;
        }

        return num;
    }

// 输入一个数字，对此数的二进制位第4 5 7置1， 将第2、6位置0, 以十六进制输出
    static public void  bitOp() {
        int num = getInt("请输入一个数: ");
        // 1010 0111 0xa7/167
        // 1101 1101 0xdd

        // 某位置1: num | (1 << bit)
        // 某位置0: num & ~(1 << bit)

        // int ret = num | (1 << 3 | 1 << 4 | 1 << 6);
        // int ret = num | (3 << 3 | 1 << 6);
        int ret = num | (0xd << 3);
        ret &= ~(1 << 1 | 1 << 5);

        System.out.printf("%d ==> %#x\n", num, ret);
    }

// 计算一个数值二进制为1的位的个数
    static public void  bitCount() {
        int num = getInt("请输入一个数: ");
        int count = 0;

        if (num < 0)
            num *= -1;

        for (int i = 0; i < 31; ++i) {
            if (((1 << i) & num) != 0) {
                ++count;
            }
        }
        p("count = %d\n", count);
    }

// 输出1-1/2+1/3-1/4+1/5...+1/99-1/100结果(结果保留两位小数)
    static public void  floatSum() {
        double sum = 1;

        for (int i = 2; i < 101; ++i) {
            if (i % 2 == 0) {
                sum -= 1.0 / i;
            } else {
                sum += 1 / (double)i;
            }
        }

        p("1 - 1/2 + 1/3 - 1/4 ... - 1/100 = %.2f\n", sum);
    }

// 把八进制的a转化为10进制的数输出
    static public void  octToDec() {
        int num = getInt("请输入八进制数: ");
        int bit = 0, mod, i, sum = 0, saveNum = num, sym = 1;

        // 145 = 1*8^2 + 4*8^1 + 5*8^0

        /*
         * num / 1 % 10
         * num / 10 % 10
         * num / 100 % 10
         * num / 1000 % 10
         * num / 10000 % 10
         */
        if (num < 0) {
            num *= -1;
            sym = -1;
        }

        while (num > 0) {
            mod = num % 10;
            if (mod > 7) {
                p("你输入的数不是八进制!\n");
                return;
            }
            for (i = 0; i < bit; ++i) {
                mod *= 8;
            }
            sum += mod;
            bit++;
            num /= 10;
        }

        sum *= sym;

        p("八进制 %d 的十进制是 %d\n", saveNum, sum);
    }

// 求两个数的最大公约数
    static public void  divisor() {
        int n1 = getInt("请输入数字1: ");
        int n2 = getInt("请输入数字2: ");
        int min;

        for (min = n1 > n2 ? n2 : n1; min > 0; --min) {
            if (n1 % min == 0 && n2 % min == 0)
                break;
        }

        p("%d 和 %d 的最大公约数是: %d\n", n1, n2, min);
    }

// 求1000以内的完数，完数的定义：所有因子之和等于该本身
    static public boolean isPrefectNum(int num) {
        int sum = 0;
        for (int i = num / 2; i > 0; --i) {
            if (num % i == 0)
                sum += i;
        }
        return (sum == num) ? true : false;
    }

    static public void  perfectNum() {
        for (int i = 1; i < 1000; ++i) {
            if (isPrefectNum(i)) {
                p("%d ", i);
            }
        }
        p("\n");
    }

// 求1000以内的水仙花数(每一位的立方之和等于该数本身);
    static public boolean isFlowerNum(int num) {
        int saveNum = num, mod, sum = 0;

        while (num > 0) {
            mod = num % 10;
            sum += mod * mod * mod;
            num /= 10;
        }
        return (sum == saveNum) ? true : false;
    }

    static public void  flowerNum() {
        for (int i = 1; i < 1000; ++i) {
            if (isFlowerNum(i)) {
                p("%d ", i);
            }
        }
        p("\n");
    }


    static public void main(String [] args) {
        int input;
        boolean quit = false;

        while (!quit) {
            System.out.println("==== 方法作业 ====");
            System.out.println("1. 交换变量!");
            System.out.println("2. 二进制位置0或1!");
            System.out.println("3. 二进制的1的个数!");
            System.out.println("4. 1-1/2+1/3....!");
            System.out.println("5. 八进制转十进制!");
            System.out.println("6. 最大公约数!");
            System.out.println("7. 完数!");
            System.out.println("8. 水仙花数!");
            System.out.println("9. 退出");
            System.out.printf("请输入[1 - 9]: ");
            input = sc.nextInt();

            System.out.printf("-------------- 华丽的分隔线 -------------\n\n");
            switch (input) {
                case 1:
                    swapVal();
                    break;
                case 2:
                    bitOp();
                    break;
                case 3:
                    bitCount();
                    break;
                case 4:
                    floatSum();
                    break;
                case 5:
                    octToDec();
                    break;
                case 6:
                    divisor();
                    break;
                case 7:
                    perfectNum();
                    break;
                case 8:
                    flowerNum();
                    break;
                case 9:
                    quit = true;
                    break;
                default:
                    break;
            }
            System.out.printf("\n-------------- 华丽的分隔线 -------------\n");
        }
    }
}
